﻿
/*
 * Javasript based on Functions(JBF) 1.03
 * 
 * Copyright(c) 2010, Fooxee (JA86.CN)
 *
 * JBF is licensed under the terms of the Open Source GPL 3.0(http://www.gnu.org/licenses/gpl.html) license. 
 * 
 * JBF's blog: http://www.cnblogs.com/JBF/
 * 
 * Created by Fooxee. at 2010.03.08  mailTo:hjccjun@163.com
 */

JBF.Ajax = JBF.ajax=function(options,runnable)
{
	return new JBF.Ajax.fn.init(options);
}

JBF.Ajax.fn={
	init : function(options)
	{
		this.setOptions(options);
		return this;
	},
	setOptions : function(options)
	{
		this.url=		options.url || '';
		this.method= 	options.method || 'GET';
		this.dataType= 	options.dataType || 'auto';
		this.async=		JBF.isBoolean(options.async) ? options.async : true;
		this.cache=		JBF.isBoolean(options.cache) ? options.cache : true;
		this.params=	JBF.isObject(options.params) ? options.params : {};
		
		this.beforeSend=JBF.isFunction(options.beforeSend) ? options.beforeSend : JBF.emptyFn;
		this.callback=	JBF.isFunction(options.callback) ? options.callback : JBF.emptyFn;
		this.error=		JBF.isFunction(options.error) ? options.error:JBF.emptyFn;
		this.complete=	JBF.isFunction(options.complete) ? options.complete : JBF.emptyFn;
		
		if(this.cache)  this.params.timespace= +new Date();
		this.pString=	this.urlEncode(this.params);
		
		if(this.method.toUpperCase()=='GET') this.url=this.urlAppend(this.url,this.pString);
		
	},
	createRequest : function()
	{
		try {return new ActiveXObject("Microsoft.XMLHTTP");}
        catch(e) {try {return new ActiveXObject("Msxml2.XMLHTTP");}
        catch(e) {try {return new XMLHttpRequest();}catch(e) {return window.createRequest();};};};	
	},
	send : function()
	{
		var dataType=this.dataType,
		xhr=this.createRequest(),
		callback=this.callback,
		error=this.error,
		complete=this.complete,
		thisObj=this;
		
		var pollHandler,
		stateHandler=function()
		{
			try
			{
				if(xhr.readyState==4)
				{
					if(xhr.status==200)
					{
						var data=xhr.responseText||xhr.responseXml;
						try
						{
						if(dataType=='json') data=JBF.jsonDecode(data); 
						callback.call(thisObj,data,xhr);
						}catch(e)
						{
							error.call(thisObj,xhr,'JSON转换错误:'+e.message);	
						}
					}
					else
					{
						error.call(thisObj,xhr,xhr.statusText);
					}
					complete.call(thisObj,xhr);
					clearTimeout(pollHandler);
				}
			}
			catch(e)
			{
				error.call(thisObj,xhr,e.message);
				complete.call(thisObj,xhr);
				clearTimeout(pollHandler);
			}
		};
		
		xhr.open(this.method,this.url,this.async);
		this.beforeSend.call(this,xhr);
		
		if(this.pString)
		{
			xhr.setRequestHeader("Content-Length", this.pString.length);   
			xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded;");
		};
		
		if(!+"\v1") xhr.onreadystatechange=stateHandler;
		try
		{
			xhr.send(this.method.toUpperCase()=='GET'?null:this.pString);
		}
		catch(e)
		{
			error.call(this,xhr,e.message);
		}
		
		if(!!+"\v1")
		{
			xhr.onreadystatechange=stateHandler();
			//异步为真时
			if(this.async)
			{
				pollHandler=setTimeout(function()
				{
					stateHandler();
				},0);
			}
		}
		
	},
	urlEncode : function(o, pre)
	{
		var empty,
		buf = [],
		e = encodeURIComponent;
		JBF.each(o,function(k,i,list)
		{
			if(!JBF.isEmpty(k)) buf.push('&', e(k), '=', e(list[k]));
		});
		buf.shift();
		return (pre || '') + buf.join('');
	},
	urlDecode : function(s)
	{
		if(JBF.isEmpty(s))
		{
			return {};	
		}
		var obj = {},
		pairs,
		d = decodeURIComponent;
		var pms=s.split('?');
		if(pms.length>1)
		{
			pms.shift();
			s=pms.join('');
		}
		pairs = s.split('&');
		
		JBF.each(pairs,function(v,i,list)
		{
			pair = v.split('=');
			obj[pair[0]] = pair[1];
		});
		return obj;
	},
	urlAppend : function(url, s)
	{
		if(!JBF.isEmpty(s))
		{
			return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
		}
		return url;
	}
}
JBF.Ajax.fn.init.prototype=JBF.Ajax.fn;

JBF.apply(JBF.Ajax,{
		  
	post:function(url,params,callback,async,cache)
	{
		return 	JBF.Ajax({url:url,params:params,callback:callback,method:'POST',dataType:'auto',async:async,cache:cache,error:callback}).send();
	},
	get:function(url,params,callback,async,cache)
	{
		return 	JBF.Ajax({url:url,params:params,callback:callback,method:'GET',dataType:'auto',async:async,cache:cache,error:callback}).send();
	},
	postJSON:function(url,params,callback,async,cache)
	{
		return 	JBF.Ajax({url:url,params:params,callback:callback,method:'POST',dataType:'json',async:async,cache:cache,error:callback}).send();
	},
	getJSON:function(url,params,callback,async,cache)
	{
		return 	JBF.Ajax({url:url,params:params,callback:callback,method:'GET',dataType:'json',async:async,cache:cache,error:callback}).send();
	},
	
	urlEncode:JBF.Ajax.fn.urlEncode,
	urlDecode:JBF.Ajax.fn.urlDecode,
	urlAppend:JBF.Ajax.fn.urlAppend
});


